#ifndef __FIBER_SINGLETON_H__
#define __FIBER_SINGLETON_H__

#include <memory>

namespace fiber 
{
namespace // 匿名命名空间在这里是「文件内私有工具函数的容器」，通过限制作用域避免命名冲突，同时隐藏单例实现的内部细节，确保代码的安全性和封装性。
{
template <class T, class X, int N>
T &GetInstanceX() {
    static T v;
    return v;
}

template <class T, class X, int N>
std::shared_ptr<T> GetInstancePtr() {
    static std::shared_ptr<T> v(new T);
    return v;
}

}  // namespace

/**
 * @brief 单例模式封装类
 * @details T 类型
 *          X 为了创造多个实例对应的Tag
 *          N 同一个Tag创造多个实例索引
 */
template <class T, class X = void, int N = 0>
class Singleton {
public:
    /**
     * @brief 返回单例裸指针
     */
    static T *GetInstance() {
        static T v;
        return &v;
        // return &GetInstanceX<T, X, N>();
    }
};

/**
 * @brief 单例模式智能指针封装类
 * @details T 类型
 *          X 为了创造多个实例对应的Tag
 *          N 同一个Tag创造多个实例索引
 */
template <class T, class X = void, int N = 0>
class SingletonPtr {
public:
    // 返回单例智能指针
    static std::shared_ptr<T> GetInstance() {
        static std::shared_ptr<T> v(new T);
        return v;
        // return GetInstancePtr<T, X, N>();
    }
};

}  // namespace fiber

#endif  // __FIBER_SINGLETON_H__